/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.meducated.sandbox.scriptingandqueues;

import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.annotations.PersistenceAware;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;

/**
 *
 * @author Greg Scott
 */
@PersistenceAware
public class DemoPatientTaskServlet extends HttpServlet {

    private static final Logger log = Logger.getLogger(DemoPatientTaskServlet.class.getName());

    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        log.info("Running the Demo Patient task!");

        PersistenceManager pm = PMF.get().getPersistenceManager();

        DemoPatient pt = null;
        // Retrieve the demo patient
        try {
            pt = pm.getObjectById(DemoPatient.class, "DemoPatient");
        } catch (JDOObjectNotFoundException e) {
        }

        if (pt == null) {
            // Don't do anything
            log.warning("The Demo Patient task could not find a patient!");
        } else {


            // Run the code within the patient!

            // Set up some objects for running the JavaScript
            // Create and enter a Context. A Context stores information about the execution environment of a script.  
            Context cx = Context.enter();
            Scriptable scope = cx.initStandardObjects();

            pm.currentTransaction().begin(); // <-------

            // Wrap up the patient into an object that can be accessed by JavaScript
            Object wrappedPt = Context.javaToJS(pt, scope);

            // Insert this into the JavaScript scope
            ScriptableObject.putProperty(scope, "pt", wrappedPt);

            // Run the JavaScript code
            Object result = cx.evaluateString(scope, pt.getCode(), "DemoPatient", 1, null);
            log.log(Level.INFO, "clock = {0}s, hr = {1}, bp = {2}/{3}", new Object[]{pt.getClock(), pt.getHr(), pt.getBp().getSbp(), pt.getBp().getDbp()});


            // Update the patient clock
            pt.setClock(pt.getClock() + 10);

            try {
                // Persist the patient
                pm.makePersistentAll(pt);
                pm.currentTransaction().commit();
            } finally {
                pm.close();
            }

            Context.exit();

            // Repeat the task
            Queue queue = QueueFactory.getQueue("demo-patient-queue");
            queue.add(TaskOptions.Builder.withUrl("/demopatienttask").countdownMillis(10000).param("key", "DemoPatient"));
        }



        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            /* TODO output your page here. You may use following sample code. */
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet PatientTaskServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet PatientTaskServlet at " + request.getContextPath() + "</h1>");
            out.println("</body>");
            out.println("</html>");
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP
     * <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP
     * <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Demo Patient task servlet";
    }// </editor-fold>
}